﻿using DotNetCommon.Extensions;
using NUnit.Framework;
using Shouldly;

namespace Test.MySql.ColumnTypeTests
{
    [TestFixture]
    internal class ColumnTypesTestsBit : TestBase
    {
        #region 模型
        public class Model
        {
            /// <summary>
            /// column: bit
            /// </summary>
            public bool? t_bit { get; set; }
            /// <summary>
            /// column: bit(8)
            /// </summary>
            public byte? t_bit8 { get; set; }
            /// <summary>
            /// column: bit(16)
            /// </summary>
            public ushort? t_bit16 { get; set; }
            /// <summary>
            /// column: bit(32)
            /// </summary>
            public uint? t_bit32 { get; set; }
            /// <summary>
            /// column: bit(64)
            /// </summary>
            public ulong? t_bit64 { get; set; }
            /// <summary>
            /// column: bit(4)
            /// </summary>
            public byte? t_bit4 { get; set; }
        }
        #endregion

        [SetUp]
        public void Setup()
        {
            DropTableIfExist("test");
            db.ExecuteSql(@"
create table test.test(
	t_bit bit,
	t_bit8 bit(8),
	t_bit16 bit(16),
	t_bit32 bit(32),
	t_bit64 bit(64),
	t_bit4 bit(4)
)");
            db.ExecuteSql("insert into test.test(t_bit,t_bit8,t_bit16,t_bit32,t_bit64,t_bit4)values(true,1,2,3,4,5)");
            db.ExecuteSql("insert into test.test(t_bit,t_bit8,t_bit16)values(0x01,0xFF,0x0001)");
            db.ExecuteSql("insert into test.test(t_bit,t_bit8)values(b'1',b'01010001')");
        }

        [Test]
        public void Test()
        {
            var dic = db.SelectDictionary("select * from test limit 1");

            dic["t_bit"].ShouldBe(1);
            dic["t_bit8"].ShouldBe(1);
            dic["t_bit16"].ShouldBe(2);
            dic["t_bit32"].ShouldBe(3);
            dic["t_bit64"].ShouldBe(4);
            dic["t_bit4"].ShouldBe(5);

            //ado统一使用 ulong解析
            dic["t_bit"].GetType().ShouldBe(typeof(ulong));
            dic["t_bit8"].GetType().ShouldBe(typeof(ulong));
            dic["t_bit16"].GetType().ShouldBe(typeof(ulong));
            dic["t_bit32"].GetType().ShouldBe(typeof(ulong));
            dic["t_bit64"].GetType().ShouldBe(typeof(ulong));
            dic["t_bit4"].GetType().ShouldBe(typeof(ulong));
        }

        [Test]
        public void Test2()
        {
            var vals = db.SelectModel<(int, uint, long, ulong, byte, short)>("select * from test limit 1");
            vals.Item1.ShouldBe(1);
            vals.Item2.ShouldBe(1u);
            vals.Item3.ShouldBe(2L);
            vals.Item4.ShouldBe(3ul);
            vals.Item5.ShouldBe((byte)4);
            vals.Item6.ShouldBe((short)5);
        }

        [Test]
        public void TestOrmRead()
        {
            var models = db.SelectModelList<Model>("select * from test");
            models[0].t_bit.ShouldBe(true);
            models[0].t_bit8.ShouldBe((byte)0x01);
            models[0].t_bit16.ShouldBe((ushort)0x0002);
            models[0].t_bit32.ShouldBe((uint)0x0000_0003);
            models[0].t_bit64.ShouldBe((ulong)0x0000_0000_0004);
            models[0].t_bit4.ShouldBe((byte)0x05);
        }

        [Test]
        public void TestOrmWrite()
        {
            TruncateTable("test");
            var model = new Model
            {
                t_bit = true,
                t_bit8 = 0x01,
                t_bit16 = 0x0002,
                t_bit32 = 0x0000_0003,
                t_bit64 = 0x0000_0000_0004,
                t_bit4 = 0x05
            };
            var sql = db.Insert("test", model.ToDictionary()).ToSql();
            var res = db.Insert("test", model.ToDictionary()).ExecuteAffrows();
            res.ShouldBe(1);
            var models = db.SelectModelList<Model>("select * from test");

            models[0].t_bit.ShouldBe(true);
            models[0].t_bit8.ShouldBe((byte)0x01);
            models[0].t_bit16.ShouldBe((ushort)0x0002);
            models[0].t_bit32.ShouldBe((uint)0x0000_0003);
            models[0].t_bit64.ShouldBe((ulong)0x0000_0000_0004);
            models[0].t_bit4.ShouldBe((byte)0x05);
        }
    }
}
